<?php

namespace App\Http\Controllers\Admin\Api;

use App\Exceptions\LogicException;
use App\Http\Controllers\Controller;
use App\Models\Api\Apis;
use App\Models\Api\ApisParam;
use App\Models\Api\SampleValue;

use App\Services\makeReportService;
use App\Services\RunTestService;
use App\Utils\QueryUtil;
use App\Utils\ResUtil;
use App\Models\Adminer\Admins;
use http\Params;

class SampleValueController extends Controller
{
    public function list()
    {
        $request = request()->all();
        $query = SampleValue::where(function($query) use($request) {
            QueryUtil::selectBuild($query, $request, [
                ['api_id', '='],
                ['param_id', '='],
                ['sample_key', 'like', 'sample_key'],
                ['sample_rule', 'like', 'sample_rule'],
                ['value_type', 'like', 'value_type'],
                ['remark', 'like', 'remark'],
                ['created_adminer', 'like', 'created_adminer'],
                ['updated_adminer', 'like', 'updated_adminer'],
                ['id', '='],
                ['status', '=']
            ]);
        });

        $total = $query->count();
        $models = QueryUtil::queryListParams($query);
        $list = [];
        foreach($models as $i => $v) {
            $list[$i] = $v?->label()?->toArray();
        }
        $hasMore = QueryUtil::hasMore(sizeof($list));
        return $this->ok(compact('list', 'total', 'hasMore'));
    }

    public function edit()
    {
        $data = request()->only([
            'id', 'api_id', 'sample_key' ,'sample_rule', 'value_type', 'remark', 'param_id'
        ]);
        $rule = [
            'id' => '',
            'api_id' => 'required',
            'sample_key' => 'required',
            'param_id' => 'required',
            'sample_rule' => 'required',
            'value_type' => 'required',
            'remark' => 'required'
        ];
        $validator = validatorService()->checkValidator($rule, $data, SampleValue::$fillables);
        if ($validator['code'] != 200) {
            throw new LogicException($validator['data']);
        }

        if(!empty($data['id'])) {
            $SampleValue = SampleValue::where('sample_key', $data['sample_key'])->first();
            if($SampleValue) {
                if($SampleValue->id !== ($data['id'])) {
                    throw new LogicException('已经存在相同名称key的取样,请重新取名');
                }
            } else {
                $SampleValue = SampleValue::find($data['id']);
            }
        } else {
            $SampleValue = new SampleValue;
            $SampleValue->sample_value = '';
            $SampleValue->status =  SampleValue::STATUS_INIT;
            $SampleValue->created_adminer = Admins::getInfoById($this->authAdmin()->id);
        }

        $api = Apis::find($data['api_id']);
        if(!$api) {
            throw new LogicException('接口不存在');
        }

        $param = ApisParam::find($data['param_id']);
        if(!$param) {
            throw new LogicException('接口参数不存在');
        }

        $SampleValue->fill([
            'api_id' => $api->id,
            'param_id' => $param->id,
            'sample_key' => $data['sample_key'],
            'sample_rule' => $data['sample_rule'],
            'value_type' => $data['value_type'],
            'remark' => $data['remark'],
            'updated_adminer' => Admins::getInfoById($this->authAdmin()->id),
        ]);
        $SampleValue->save();
        return $this->ok();
    }

    public function enable()
    {
        $data = request()->all();
        $rule = [
            'id' => 'integer|required',
        ];
        $validator = validatorService()->checkValidator($rule, $data, SampleValue::$fillables);
        if ($validator['code'] != 200) {
            throw new LogicException($validator['data']);
        }
        $ApisParam = SampleValue::find($data['id']);
        if(!$ApisParam) {
            throw new LogicException(ResUtil::NOT_DATA);
        }
        $ApisParam->delete();
        return $this->ok();
    }

    public function moreSampleValues(RunTestService $runTestService, makeReportService $makeReportService)
    {
        $data = request()->all();
        $rule = [
            'params_ids' => 'array|required',
        ];
        $validator = validatorService()->checkValidator($rule, $data, SampleValue::$fillables);
        if ($validator['code'] != 200) {
            throw new LogicException($validator['data']);
        }
        $params = ApisParam::whereIn('id', $data['params_ids'])->orderByDesc('id')->get();
        foreach($params as $param) {
            $api = Apis::find($param->api_id);
            $api_info = $makeReportService->getUrl($api->api);
            $url = $api_info['scheme']."://".$api_info['domain'].$api_info['path'];
            if(!empty($api_info['port'])) {
                $url = $api_info['scheme']."://".$api_info['domain'] .':'.$api_info['port'].$api_info['path'];
            }
            $param1 = json_decode(json_encode($param->param), true);
            $headers1  = Apis::getHeaders($api) ?: [];
            $params = $runTestService->getSampleValue($param1);
            $headers =  $runTestService->getSampleValue($headers1);
            $method = Apis::$method_type_maps[$api->method_type] ?? "POST";
            $res = $runTestService->initServe()->curlRun($url, $params, $headers, $method);

            // 取样器
            $sampleValues =  SampleValue::getBYParamID($param->id);
            if(empty($sampleValues?->toArray())) {
                continue;
            }
            $biao1 = false;
            foreach($sampleValues as $sampleValue) {
                $param_res = $res['res_body']; // array
                $sample_rule = $sampleValue->sample_rule; // $.data.list.0.id
                $arr_rule = explode('.', $sample_rule);

                foreach ($arr_rule as $rule) {
                    if ($rule == '$') {
                        continue;
                    }
                    if(!isset($param_res[$rule])) {
                        //  // 0未取样 1取样成功 2取样失败
                        $sampleValue->status = SampleValue::STATUS_FAIL;
                        $sampleValue->save();
                        $biao1 = true;
                        break;
                    }
                    $param_res = $param_res[$rule];
                }
                if ($biao1) {
                    $biao1 = false;
                    continue;
                }
                $sampleValue->status = SampleValue::STATUS_SUCCESS;
                $sampleValue->sample_value = $param_res;
                $sampleValue->save();
            }
        }
        return $this->ok();
    }

}
